package com.wpw.dream.concurrent;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Semaphore（信号量）是用来控制同时访问特定资源的线程数量，它通过协调各个线程，以保证合理的使用公共资源，就好比现在的旅游景点限流。
 * 主要方法：
 * acquire()：从此信号量获取一个许可，在提供一个许可前一直将线程阻塞，否则线程被中断。 获取一个许可（如果提供了一个）并立即返回，将可用的许可数减 1。 
 * release()：释放一个许可，将其返回给信号量，即：将可用的许可数增加 1
 * 
 * 最好将释放许可的调用放入finally代码块中，这样，即使数据处理过程中出现异常，也能保证释放了许可。
 * 
 * 其他方法
	Semaphore还提供一些其他方法：
	    int availablePermits() ：返回此信号量中当前可用的许可证数。
	    int getQueueLength()：返回正在等待获取许可证的线程数。
	    boolean hasQueuedThreads() ：是否有线程正在等待获取许可证。
	    void reducePermits(int reduction) ：减少reduction个许可证。是个protected方法。
	    Collection getQueuedThreads() ：返回所有等待获取许可证的线程集合。是个protected方法。
 * 
 * Project Name：dream-test
 * ClassName：SemaphoreTest
 * Description：
 * @author: wupengwei
 * @date: 2017年5月25日 上午10:23:34
 * note:
 *
 */
public class SemaphoreTest {

	private static final int THREAD_COUNT = 30;
	
	static AtomicInteger ai = new AtomicInteger();

	private static ExecutorService threadPool = Executors
			.newFixedThreadPool(THREAD_COUNT);

	private static Semaphore s = new Semaphore(5);

	public static void main(String[] args) {
		for (int i = 0; i < THREAD_COUNT; i++) {
			threadPool.execute(new Runnable() {
				@Override
				public void run() {
					try {
						s.acquire();
						System.out.println("save data" + ai.getAndIncrement());
						Thread.sleep(2000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					} finally {
						s.release();
					}
					
				}
			});
		}

		threadPool.shutdown();
	}
}
